/*
 * SPDX-FileCopyrightText: 2023-2025 Andrew Gunnerson
 * SPDX-License-Identifier: GPL-3.0-only
 */

package com.sanji.audio_test.output

import android.content.Context
import com.sanji.audio_test.format.FormatParamInfo
import com.sanji.audio_test.format.NoParamInfo
import com.sanji.audio_test.format.RangedParamInfo
import com.sanji.audio_test.format.RangedParamType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter

/**
 * 通话方向枚举
 */
@Serializable
enum class CallDirection {
    @SerialName("in")
    IN,           // 呼入
    @SerialName("out")
    OUT,          // 呼出
    @SerialName("conference")
    CONFERENCE,   // 会议通话
}

/**
 * 通话参与方详细信息
 *
 * @param phoneNumber 电话号码
 * @param callerName 来电者名称
 * @param contactName 联系人名称
 */
data class CallPartyDetails(
    val phoneNumber: PhoneNumber?,
    val callerName: String?,
    val contactName: String?,
)

/**
 * 通话参与方详细信息的JSON序列化版本
 */
@Serializable
data class CallPartyDetailsJson(
    @SerialName("phone_number")
    val phoneNumber: String?,                    // 电话号码
    @SerialName("phone_number_formatted")
    val phoneNumberFormatted: String?,           // 格式化的电话号码
    @SerialName("caller_name")
    val callerName: String?,                     // 来电者名称
    @SerialName("contact_name")
    val contactName: String?,                    // 联系人名称
) {
    /**
     * 从CallPartyDetails构造CallPartyDetailsJson
     */
    constructor(context: Context, details: CallPartyDetails) : this(
        phoneNumber = details.phoneNumber?.toString(),
        phoneNumberFormatted = details.phoneNumber
            ?.format(context, PhoneNumber.Format.COUNTRY_SPECIFIC),
        callerName = details.callerName,
        contactName = details.contactName,
    )
}

/**
 * 通话元数据
 *
 * @param timestamp 通话时间戳
 * @param direction 通话方向
 * @param simCount SIM卡数量
 * @param simSlot SIM卡槽位
 * @param callLogName 通话记录名称
 * @param calls 通话参与方列表
 */
data class CallMetadata(
    val timestamp: ZonedDateTime,
    val direction: CallDirection?,
    val simCount: Int?,
    val simSlot: Int?,
    val callLogName: String?,
    val calls: List<CallPartyDetails>,
)

/**
 * 通话元数据的JSON序列化版本
 */
@Serializable
data class CallMetadataJson(
    @SerialName("timestamp_unix_ms")
    val timestampUnixMs: Long,        // 时间戳（Unix毫秒）
    val timestamp: String,            // ISO格式时间字符串
    val direction: CallDirection?,    // 通话方向
    @SerialName("sim_slot")
    val simSlot: Int?,                // SIM卡槽位
    @SerialName("call_log_name")
    val callLogName: String?,         // 通话记录名称
    val calls: List<CallPartyDetailsJson>, // 通话参与方列表
    val output: OutputJson,           // 输出信息
) {
    /**
     * 从CallMetadata构造CallMetadataJson
     */
    constructor(context: Context, metadata: CallMetadata, output: OutputJson) : this(
        timestampUnixMs = metadata.timestamp.toInstant().toEpochMilli(),
        timestamp = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(metadata.timestamp),
        direction = metadata.direction,
        simSlot = metadata.simSlot,
        callLogName = metadata.callLogName,
        calls = metadata.calls.map { CallPartyDetailsJson(context, it) },
        output = output,
    )
}

/**
 * 参数类型枚举
 */
@Serializable
enum class ParameterType {
    @SerialName("none")
    NONE,                    // 无参数
    @SerialName("compression_level")
    COMPRESSION_LEVEL,       // 压缩级别
    @SerialName("bitrate")
    BITRATE,                 // 比特率
    ;

    companion object {
        /**
         * 从FormatParamInfo创建ParameterType
         */
        fun fromParamInfo(info: FormatParamInfo): ParameterType = when (info) {
            NoParamInfo -> NONE
            is RangedParamInfo -> when (info.type) {
                RangedParamType.CompressionLevel -> COMPRESSION_LEVEL
                RangedParamType.Bitrate -> BITRATE
            }
        }
    }
}

/**
 * 格式信息的JSON序列化版本
 */
@Serializable
data class FormatJson(
    val type: String,                          // 格式类型
    @SerialName("mime_type_container")
    val mimeTypeContainer: String,             // 容器MIME类型
    @SerialName("mime_type_audio")
    val mimeTypeAudio: String,                 // 音频MIME类型
    @SerialName("parameter_type")
    val parameterType: ParameterType,          // 参数类型
    val parameter: UInt,                       // 参数值
)

/**
 * 录制信息的JSON序列化版本
 */
@Serializable
data class RecordingJson(
    @SerialName("frames_total")
    val framesTotal: Long,              // 总帧数
    @SerialName("frames_encoded")
    val framesEncoded: Long,            // 已编码帧数
    @SerialName("sample_rate")
    val sampleRate: Int,                // 采样率
    @SerialName("channel_count")
    val channelCount: Int,              // 声道数
    @SerialName("duration_secs_wall")
    val durationSecsWall: Double,       // 实际时长（秒）
    @SerialName("duration_secs_total")
    val durationSecsTotal: Double,      // 总时长（秒）
    @SerialName("duration_secs_encoded")
    val durationSecsEncoded: Double,    // 编码时长（秒）
    @SerialName("buffer_frames")
    val bufferFrames: Long,             // 缓冲帧数
    @SerialName("buffer_overruns")
    val bufferOverruns: Int,            // 缓冲区溢出次数
    @SerialName("was_ever_paused")
    val wasEverPaused: Boolean,         // 是否曾暂停
    @SerialName("was_ever_holding")
    val wasEverHolding: Boolean,        // 是否曾保持
)

/**
 * 输出信息的JSON序列化版本
 */
@Serializable
data class OutputJson(
    val format: FormatJson,      // 格式信息
    val recording: RecordingJson?, // 录制信息
)